from docx import Document
from docx.shared import Pt
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.oxml.ns import qn
from docx.shared import Inches
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QFileDialog, QVBoxLayout, QWidget, QLineEdit, QMessageBox
from PyQt5.QtCore import Qt
import json,os,datetime,hashlib,binascii,shutil,subprocess,sys

current_directory = os.getcwd()
parent_directory = os.path.dirname(current_directory)
json_file = "data.json"

def read_json_file(file_path):
    try:
        with open(file_path, 'r', encoding="utf-8") as file:
            data = json.load(file)
            return data
    except Exception as e:
        print(f"Error opening JSON file: {e}")

file_path = os.path.join(current_directory, json_file)
json_data = read_json_file(file_path)

#MD5校验
def calculate_checksum(filename, algorithm='md5', chunk_size=8192):
    hash_algorithm = hashlib.new(algorithm)
    with open(filename, 'rb') as file:
        while chunk := file.read(chunk_size):
            hash_algorithm.update(chunk)
    return hash_algorithm.hexdigest()

#CRC校验
def calculate_crc(filename):
    buffer_size = 8192  # 缓冲区大小，你可以根据需要进行调整
    crc32_value = 0xFFFFFFFF

    with open(filename, "rb") as file:
        while True:
            data = file.read(buffer_size)
            if not data:
                break
            crc32_value = binascii.crc32(data, crc32_value)

    crc_value = format(crc32_value & 0xFFFFFFFF, "08x")
    return crc_value

def get_check_code():
    checksum = calculate_checksum(json_data["check_code_file"])
    if checksum is None:
        print(f"打开{json_data['check_code_file']}失败\n")
        return None
    else:
        return checksum
    
def delete_file_if_exists(filename):
    if os.path.exists(filename):
        os.remove(filename)
        # print(f"文件'{filename}'已删除")
        return 1
    else:
        # print(f"文件'{filename}'不存在")
        return 0

def create_doc(json_data):
    # 创建一个新的Word文档
    doc = Document()

    # 设置页边距（单位为英寸）
    margin_left = Inches(0.5)
    margin_right = Inches(0.5)
    margin_top = Inches(0.5)
    margin_bottom = Inches(0.5)

    sections = doc.sections
    for section in sections:
        section.left_margin = margin_left
        section.right_margin = margin_right
        section.top_margin = margin_top
        section.bottom_margin = margin_bottom

    # 添加标题
    head_name = f"{json_data['city_name']}{json_data['company']}{json_data['doc_type']}\n"

    title = doc.add_heading(level=1)
    title_run = title.add_run(head_name)

    title.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER  # 居中对齐
    title_run.font.size = Pt(25)  # 字体大小为25磅
    title_run.font.name = '宋体'
    title_run._element.rPr.rFonts.set(qn('w:eastAsia'),'宋体')

    # 添加列表
    current_time = str(datetime.date.today())
    name = json_data["name"]
    soc = json_data["soc"]
    board = json_data["board"]
    sdk = json_data["sdk"]
    Paired_name = json_data["Paired_name"]
    software_id = f"{current_time}_{board}_({Paired_name})_{get_check_code()}"
    check_code = get_check_code()

    list_items = [
        '主控名称',
        '客户机型',
        'SDK版本',
        '配对名',
        '软件编号',
        '烧录校验码',
        '编译生成',
        '送样部门'
    ]

    list_data = [
        soc,
        board,
        sdk,
        Paired_name,
        software_id,
        check_code,
        '是',
        '研发部'
    ]

    font_size = Pt(20)
    list_paragraph = doc.add_paragraph()

    # 遍历列表，并将组合后的数据添加到文档中
    for item, data in zip(list_items, list_data):
        run = list_paragraph.add_run(f"{item}:")
        run.font.name = '宋体'
        run._element.rPr.rFonts.set(qn('w:eastAsia'),'宋体')
        run.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT  # 左对齐
        run.font.size = font_size
        run.bold = True

        run1 = list_paragraph.add_run(f"{data}\n")
        run1.font.name = '宋体'
        run1._element.rPr.rFonts.set(qn('w:eastAsia'),'宋体')
        run1.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT  # 左对齐
        run1.font.size = Pt(15)
        run1.font.underline = True  # 设置为下划线

    # 添加表格，设置表格行数和列数
    num_rows = 1
    num_cols = 4
    table = doc.add_table(rows=num_rows + 1, cols=num_cols)

    # 设置表格的高度
    table_height = Inches(0.5)
    for row in table.rows:
        row.height = table_height

    # 设置表格样式
    table.style = 'Table Grid'

    # 设置表头内容和样式
    header_labels = ['核准', '确认', '主办', '主控名称']
    hdr_cells = table.rows[0].cells
    for idx, label in enumerate(header_labels):
        cell = hdr_cells[idx]
        cell.text = label
        cell.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
        run = cell.paragraphs[0].runs[0]
        run.bold = True
        run.font.size = Pt(20)
        run.font.name = '宋体'
        run._element.rPr.rFonts.set(qn('w:eastAsia'),'宋体')

    # 获取第二行的第一个和第四个单元格
    cell_name = table.rows[1].cells[0]
    cell_soc = table.rows[1].cells[3]

    # 设置文字内容
    cell_name.text = name
    cell_soc.text = soc

    # 设置文字居中对齐
    cell_name.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
    cell_soc.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

    # 设置文字大小为20磅
    cell_name.paragraphs[0].runs[0].font.size = Pt(20)
    cell_soc.paragraphs[0].runs[0].font.size = Pt(20)

    cell_name.paragraphs[0].runs[0].font.name = '宋体'
    cell_name.paragraphs[0].runs[0]._element.rPr.rFonts.set(qn('w:eastAsia'),'宋体')
    cell_soc.paragraphs[0].runs[0].font.name = '宋体'
    cell_soc.paragraphs[0].runs[0]._element.rPr.rFonts.set(qn('w:eastAsia'),'宋体')

    run2 = doc.add_paragraph().add_run(f"贵司确认流程：")
    run2.font.name = '宋体'
    run2._element.rPr.rFonts.set(qn('w:eastAsia'),'宋体')
    run2.font.size = font_size
    run2.bold = True

    # 添加表格，设置表格行数和列数
    table1 = doc.add_table(rows=num_rows + 1, cols=num_cols)

    # 设置表格的高度
    for row in table1.rows:
        row.height = table_height

    # 设置表格样式
    table1.style = 'Table Grid'

    # 设置表头内容和样式
    hdr_cells1 = table1.rows[0].cells
    for idx, label in enumerate(header_labels):
        cell = hdr_cells1[idx]
        cell.text = label
        cell.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
        run = cell.paragraphs[0].runs[0]
        run.bold = True
        run.font.size = Pt(20)
        run.font.name = '宋体'
        run._element.rPr.rFonts.set(qn('w:eastAsia'),'宋体')

    # 添加图片
    # doc.add_paragraph("以下是一张示例图片：")
    # doc.add_picture('example_image.jpg', width=Document.DEFAULT_WIDTH)

    # 保存文档
    doc_name = software_id+json_data['doc_type']
    doc.save(doc_name+'.docx')
    print("文档已生成并保存")
    return doc_name

def create_folder(folder_path):
    if os.path.exists(folder_path):
        shutil.rmtree(folder_path)
        os.makedirs(folder_path)
    else:
        os.makedirs(folder_path)

def create_zip(zip_path):
    if os.path.exists(zip_path):
        shutil.make_archive(f"{zip_path}.zip", 'zip', zip_path)
        shutil.rmtree(zip_path)
        print(f"'{zip_path}' 打包完成。")
    else:
        print(f"文件夹 '{zip_path}' 不存在。")

def cmd_send(cmd_command):
    try:
        subprocess.run(cmd_command, shell=True, text=True, capture_output=True, check=True)

    except subprocess.CalledProcessError as e:
        print("命令执行失败:", e)
    except Exception as e:
        print("发生异常:", e)

def copy_files(source_folder, destination_folder, file_name):
    try:
        source_path = os.path.join(source_folder, file_name)
        destination_path = os.path.join(destination_folder, file_name)
        shutil.copy(source_path, destination_path)
        return True  # 返回True表示复制成功
    except shutil.Error as e:
        return False  # 返回False表示复制失败
    except IOError as e:
        return False
    except Exception as e:
        return False

class SelectableLabel(QLabel):
    def __init__(self, text):
        super().__init__(text)

        self.setSelectable(True)

    def setSelectable(self, selectable):
        if selectable:
            self.setTextInteractionFlags(Qt.TextSelectableByMouse)
        else:
            self.setTextInteractionFlags(Qt.NoTextInteraction)

class Mainapp(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle('承认书生成器')
        self.setGeometry(100, 100, 400, 400)

        self.initUI()

    def initUI(self):

        layout = QVBoxLayout()
        self.error_test = ""

        # 创建标签和输入框
        label_info = [
            '承认人:', 
            '芯片型号:', 
            '板号:', 
            '配对名:', 
            'SDK版本:'
        ]

        self.json_data_id = [
                'name',
                'soc',
                'board',
                'Paired_name',
                'sdk'
            ]

        self.labels = []
        self.input_boxes = []

        for text,json_data_id in zip(label_info,self.json_data_id):
            label = QLabel(text)
            input_box = QLineEdit()
            if json_data is not None:
                input_box.setPlaceholderText(json_data.get(json_data_id, ""))
            else:
                print("json为空")
            self.labels.append(label)
            self.input_boxes.append(input_box)

            layout.addWidget(label)
            layout.addWidget(input_box)

        self.label = SelectableLabel('文件夹:未选择文件夹')
        layout.addWidget(self.label)

        self.button = QPushButton('选择文件夹')
        self.button.clicked.connect(self.selectFolder)
        layout.addWidget(self.button)

        self.button = QPushButton('确认')
        self.button.clicked.connect(self.confirmation)
        layout.addWidget(self.button)

        self.central_widget = QWidget()
        self.central_widget.setLayout(layout)
        self.setCentralWidget(self.central_widget)

        self.selected_folder = None

        self.show()

    def selectFolder(self):
        options = QFileDialog.Options()
        options |= QFileDialog.ShowDirsOnly

        folder = QFileDialog.getExistingDirectory(self, '请选择升级文件所在目录', options=options)

        if folder:
            self.selected_folder = folder
            self.label.setText(f'文件夹: {folder}')

    def show_error_message(self):
        QMessageBox.critical(None, '错误', self.error_test)

    def confirmation(self):
        if self.selected_folder == None:
            self.error_test = "没有选择文件夹"
            self.show_error_message()
        else:
            for file in json_data['file']:
                if not copy_files(self.selected_folder, current_directory, file):
                    self.error_test = f"{file}没找到" 
                    self.show_error_message()
                    for file in json_data['file']:
                        if delete_file_if_exists(file) is None:
                            return

            for json_data_id,get_data in zip(self.json_data_id,self.input_boxes):
                if get_data.text():
                    json_data[json_data_id] = get_data.text()

            doc_name = create_doc(json_data)
            doc_file = doc_name+'.docx'
            create_folder(doc_name)

            source_folder = current_directory
            destination_folder = doc_name
            keywords = json_data['file']+[doc_file]

            # 列出源文件夹中所有文件
            files = os.listdir(source_folder)

            for file in files:
                for keyword in keywords:
                    if keyword in file:
                        source_file = os.path.join(source_folder, file)
                        shutil.move(source_file, destination_folder)
                        print(f"移动文件 {file} 成功！")
                        break  # 如果找到匹配关键词就跳出内循环
            print("所有选定文件移动完成！")

            # 打包文件夹
            # create_zip(doc_name)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Mainapp()
    sys.exit(app.exec_())